package com.unistec.fileserver.server;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.springframework.beans.factory.ObjectFactory;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.support.ResponseEntityDecoder;
import org.springframework.cloud.openfeign.support.SpringDecoder;
import org.springframework.cloud.openfeign.support.SpringEncoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.hnit.auth.client.interceptor.ServiceAuthRestInterceptor;
import com.hnit.auth.client.interceptor.UserAuthRestInterceptor;
import com.hnit.common.handler.GlobalExceptionHandler;

/**
 * 适配器
 * 
 * @description
 * @author 胡晓光
 * @date 2021-9-29
 * @time 10:20:42
 *
 */
@SuppressWarnings("deprecation")
@Configuration
@EnableWebMvc
public class WebMVCConfigAdapter extends WebMvcConfigurerAdapter {
	@Bean
	GlobalExceptionHandler getGlobalExceptionHandler() {
		return new GlobalExceptionHandler();
	}

	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(getServiceAuthRestInterceptor()).addPathPatterns(getIncludePathPatterns());
		registry.addInterceptor(getUserAuthRestInterceptor()).addPathPatterns(getIncludePathPatterns());
	}
	
	@Bean
	ServiceAuthRestInterceptor getServiceAuthRestInterceptor() {
		return new ServiceAuthRestInterceptor();
	}

	@Bean
	UserAuthRestInterceptor getUserAuthRestInterceptor() {
		return new UserAuthRestInterceptor();
	}
	
	/**
	 * 
	 * @Title: getIncludePathPatterns @Description: 需要用户和服务认证判断的路径 @param @return
	 * 参数 @return ArrayList<String> 返回类型 @throws
	 */
	private ArrayList<String> getIncludePathPatterns() {
		ArrayList<String> list = new ArrayList<>();
		String[] urls = { 
				"/manager/**"
				};
		Collections.addAll(list, urls);
		return list;
	}
	
	@Override
	public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
		super.configureMessageConverters(converters);
		FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
		// 处理中文乱码问题
		List<MediaType> fastMediaTypes = new ArrayList<>();
		fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
		fastConverter.setSupportedMediaTypes(fastMediaTypes);

		// 处理字符串, 避免直接返回字符串的时候被添加了引号
		StringHttpMessageConverter smc = new StringHttpMessageConverter(Charset.forName("UTF-8"));
		converters.add(smc);
		converters.add(fastConverter);
	}

	@SuppressWarnings("rawtypes")
	@Bean
	public ResponseEntityDecoder feignDecoder() {
		HttpMessageConverter fastJsonConverter = createFastJsonConverter();
		ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(fastJsonConverter);
		return new ResponseEntityDecoder(new SpringDecoder(objectFactory));
	}

	@SuppressWarnings("rawtypes")
	@Bean
	public SpringEncoder feignEncoder() {
		HttpMessageConverter fastJsonConverter = createFastJsonConverter();
		ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(fastJsonConverter);
		return new SpringEncoder(objectFactory);
	}

	@SuppressWarnings("rawtypes")
	private HttpMessageConverter createFastJsonConverter() {
		FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
		// 处理中文乱码问题
		List<MediaType> fastMediaTypes = new ArrayList<>();
		fastMediaTypes.add(MediaType.APPLICATION_JSON);
		fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
		fastMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED);

		fastConverter.setSupportedMediaTypes(fastMediaTypes);

		return fastConverter;
	}
}
